package com.example.chirdrenserver.confg;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class RabbitMQConfig {

    // 交换机名称
    public static final String POST_SEND_EXCHANGE = "postSendExchange";
    public static final String HISTORY_EXCHANGE = "historyExchange";
    public static final String CLEAN_HISTORY_EXCHANGE = "cleanHistoryExchange";
    // 队列名称
    public static final String POST_SEND_QUEUE = "postSendQueue";
    public static final String POST_ADD_QUEUE = "postAddQueue";
    public static final String POST_ADD_CONTENT_QUEUE = "postAddContentQueue";
    public static final String HISTORY_QUEUE = "historyQueue";
    public static final String CLEAN_HISTORY_QUEUE = "cleanHistoryQueue";
    // 路由键
    public static final String POST_SEND_ROUTING_KEY = "post.send";
    public static final String POST_ADD_ROUTING_KEY = "post.add";
    public static final String POST_CONTENT_ADD_ROUTING_KEY = "post.content.add";
    public static final String HISTORY_ROUTING_KEY = "history.get";
    public static final String CLEAN_HISTORY_ROUTING_KEY = "history.clean";
    // 死信队列配置
    public static final String DLX_EXCHANGE = "postSendDlxExchange";
    public static final String DLX_QUEUE = "postSendDlxQueue";
    public static final String DLX_ROUTING_KEY = "post.send.dlx";

    public static final String HISTORY_DLX_EXCHANGE = "historyDlxExchange";
    public static final String HISTORY_DLX_QUEUE = "historyDlxQueue";
    public static final String HISTORY_DLX_ROUTING_KEY = "history.dlx";

    public static final String CLEAN_HISTORY_DLX_EXCHANGE = "cleanHistoryDlxExchange";
    public static final String CLEAN_HISTORY_DLX_QUEUE = "cleanHistoryDlxQueue";
    public static final String CLEAN_HISTORY_DLX_ROUTING_KEY = "history.clean.dlx";

    // 声明主题交换机
    @Bean
    public TopicExchange postExchange() {
        return ExchangeBuilder.topicExchange(POST_SEND_EXCHANGE)
                .durable(true)
                .build();
    }

    @Bean
    public TopicExchange historyExchange() {
        return ExchangeBuilder.topicExchange(HISTORY_EXCHANGE)
                .durable(true)
                .build();
    }

    @Bean
    public TopicExchange historyCleanExchange() {
        return ExchangeBuilder.topicExchange(CLEAN_HISTORY_EXCHANGE)
                .durable(true)
                .build();
    }
    // 声明队列（带死信队列配置）
    @Bean
    public Queue postSendQueue() {
        return QueueBuilder.durable(POST_SEND_QUEUE)
                .withArgument("x-dead-letter-exchange", DLX_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DLX_ROUTING_KEY)
                .build();
    }
    @Bean
    public Queue postAddQueue() {
        return QueueBuilder.durable(POST_ADD_QUEUE)
                .build();
    }
    @Bean
    public Queue postAddContentQueue() {
        return QueueBuilder.durable(POST_ADD_CONTENT_QUEUE)
                .build();
    }



    @Bean
    public Queue historyCleanQueue() {
        return QueueBuilder.durable(CLEAN_HISTORY_QUEUE)
                .withArgument("x-dead-letter-exchange", HISTORY_DLX_EXCHANGE)
                .withArgument("x-dead-letter-routing-key",HISTORY_DLX_ROUTING_KEY)
                .build();
    }
    @Bean
    public Queue historyQueue() {
        return QueueBuilder.durable(HISTORY_QUEUE)
                .withArgument("x-dead-letter-exchange", CLEAN_HISTORY_DLX_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", CLEAN_HISTORY_DLX_ROUTING_KEY)
                .build();
    }
    // 绑定队列到交换机
    @Bean
    public Binding hotRankBinding() {
        return BindingBuilder.bind(postSendQueue())
                .to(postExchange())
                .with(POST_SEND_ROUTING_KEY);
    }
    @Bean
    public Binding postAddContentBinding() {
        return BindingBuilder.bind(postAddContentQueue())
                .to(postExchange())
                .with(POST_CONTENT_ADD_ROUTING_KEY);
    }
    @Bean
    public Binding postAddBinding() {
        return BindingBuilder.bind(postAddQueue())
                .to(postExchange())
                .with(POST_ADD_ROUTING_KEY);
    }
    @Bean
    public Binding historyCleanBinding() {
        return BindingBuilder.bind(postSendQueue())
                .to(postExchange())
                .with(HISTORY_ROUTING_KEY);
    }
    @Bean
    public Binding historyBinding() {
        return BindingBuilder.bind(postSendQueue())
                .to(postExchange())
                .with(CLEAN_HISTORY_ROUTING_KEY);
    }

    // 配置JSON消息转换器
    @Bean
    public Jackson2JsonMessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    // 配置RabbitTemplate
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setMessageConverter(jsonMessageConverter());

        // 消息发送到交换器确认回调
        template.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.info("消息成功发送到交换器: {}", correlationData);
            } else {
                log.error("消息发送到交换器失败: {}, 原因: {}", correlationData, cause);
            }
        });

        // 消息路由到队列失败回调
        template.setReturnsCallback(returned -> {
            log.error("消息路由到队列失败: 交换机[{}], 路由键[{}], 消息[{}], 原因: {}",
                    returned.getExchange(),
                    returned.getRoutingKey(),
                    new String(returned.getMessage().getBody()),
                    returned.getReplyText());
        });

        return template;
    }

    // 配置消费者容器工厂
    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
            ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(jsonMessageConverter());
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); // 手动确认
        factory.setConcurrentConsumers(5); // 并发消费者数
        factory.setMaxConcurrentConsumers(10); // 最大并发数
        factory.setPrefetchCount(10); // 预取数量
        return factory;
    }

    // 死信交换机配置
    @Bean
    public DirectExchange dlxExchange() {
        return new DirectExchange(DLX_EXCHANGE, true, false);
    }
    @Bean
    public DirectExchange historyDlxExchange() {
        return new DirectExchange(HISTORY_DLX_EXCHANGE, true, false);
    }

    @Bean
    public DirectExchange cleanHistoryDlxExchange() {
        return new DirectExchange(CLEAN_HISTORY_DLX_EXCHANGE, true, false);
    }

    @Bean
    public Queue dlxQueue() {
        return new Queue(DLX_QUEUE, true);
    }
    @Bean
    public Queue historyDlxQueue() {
        return new Queue(HISTORY_DLX_QUEUE, true);
    }

    @Bean
    public Queue cleanHistoryDlxQueue() {
        return new Queue(CLEAN_HISTORY_DLX_QUEUE, true);
    }

    @Bean
    public Binding dlxBinding() {
        return BindingBuilder.bind(dlxQueue())
                .to(dlxExchange())
                .with(DLX_ROUTING_KEY);
    }


    @Bean
    public Binding HistoryDlxBinding() {
        return BindingBuilder.bind(dlxQueue())
                .to(dlxExchange())
                .with(HISTORY_DLX_ROUTING_KEY);
    }

    @Bean
    public Binding cleanHistoryDlxBinding() {
        return BindingBuilder.bind(dlxQueue())
                .to(dlxExchange())
                .with(CLEAN_HISTORY_ROUTING_KEY);
    }
}